`define SM4_BASE_ADDR    	16'h000 	//1f20_0000
`define SM3_BASE_ADDR    	16'h100 	//1f20_0100
`define SM2_BASE_ADDR    	16'h200		//1f20_0200
`define KEY_BASE_ADDR    	16'h400		//1f20_0400
`define SIMU_FLAG_ADDR      16'hf500 	//1f20_f500

//使能软件读取内部密钥
//`define ENABLE_SOFTWARE_KEY_OUT

module axi_crypto #(
    parameter   SIMULATION=1'b0
)
(
    input           aclk,
    input           aresetn,

    input           sm2_clk,
    input           sm2_resetn,

    input  [4 :0]   s_awid,
    input  [31:0]   s_awaddr,
    input  [7 :0]   s_awlen,
    input  [2 :0]   s_awsize,
    input  [1 :0]   s_awburst,
    input           s_awlock,
    input  [3 :0]   s_awcache,
    input  [2 :0]   s_awprot,
    input           s_awvalid,
    output          s_awready,
    input  [4 :0]   s_wid,
    input  [31:0]   s_wdata,
    input  [3 :0]   s_wstrb,
    input           s_wlast,
    input           s_wvalid,
    output reg      s_wready,
    output [4 :0]   s_bid,
    output [1 :0]   s_bresp,
    output reg      s_bvalid,
    input           s_bready,
    input  [4 :0]   s_arid,
    input  [31:0]   s_araddr,
    input  [7 :0]   s_arlen,
    input  [2 :0]   s_arsize,
    input  [1 :0]   s_arburst,
    input           s_arlock,
    input  [3 :0]   s_arcache,
    input  [2 :0]   s_arprot,
    input           s_arvalid,
    output          s_arready,
    output [4 :0]   s_rid,
    output reg [31:0]   s_rdata,
    output [1 :0]   s_rresp,
    output reg      s_rlast,
    output reg      s_rvalid,
    input           s_rready,
	
	output 			sm2_done_int,
	output 			sm3_done_int,
	output 			sm4_done_int
);

reg busy,write,R_or_W;

wire [31:0] rdata_d;

wire ar_enter = s_arvalid & s_arready;
wire r_retire = s_rvalid & s_rready & s_rlast;
wire aw_enter = s_awvalid & s_awready;
wire w_enter  = s_wvalid & s_wready & s_wlast;
wire b_retire = s_bvalid & s_bready;

assign s_arready = ~busy & (!R_or_W| !s_awvalid);
assign s_awready = ~busy & ( R_or_W| !s_arvalid);

//busy signal
always@(posedge aclk)
begin
    if(~aresetn) busy <= 1'b0;
    else if(ar_enter|aw_enter) busy <= 1'b1;
    else if(r_retire|b_retire) busy <= 1'b0;
end

reg  [31:0] simu_flag;

reg [4 :0] buf_id;
reg [31:0] buf_addr;
reg [7 :0] buf_len;
reg [2 :0] buf_size;
reg [1 :0] buf_burst;
reg        buf_lock;
reg [3 :0] buf_cache;
reg [2 :0] buf_prot;

always@(posedge aclk)
begin
    if(~aresetn) begin
        R_or_W      <= 1'b0;
        buf_id      <= 'b0;
        buf_addr    <= 'b0;
        buf_len     <= 'b0;
        buf_size    <= 'b0;
        buf_burst   <= 'b0;
        buf_lock    <= 'b0;
        buf_cache   <= 'b0;
        buf_prot    <= 'b0;
    end
    else
    if(ar_enter | aw_enter) begin
        R_or_W      <= ar_enter;
        buf_id      <= ar_enter ? s_arid   : s_awid   ;
        buf_addr    <= ar_enter ? s_araddr : s_awaddr ;
        buf_len     <= ar_enter ? s_arlen  : s_awlen  ;
        buf_size    <= ar_enter ? s_arsize : s_awsize ;
        buf_burst   <= ar_enter ? s_arburst: s_awburst;
        buf_lock    <= ar_enter ? s_arlock : s_awlock ;
        buf_cache   <= ar_enter ? s_arcache: s_awcache;
        buf_prot    <= ar_enter ? s_arprot : s_awprot ;
    end
end

//write
always@(posedge aclk)
begin
    if(~aresetn) write <= 1'b0;
    else if(aw_enter) write <= 1'b1;
    else if(ar_enter)  write <= 1'b0;
end

//wready
always@(posedge aclk)
begin
    if(~aresetn) s_wready <= 1'b0;
    else if(aw_enter) s_wready <= 1'b1;
    else if(w_enter & s_wlast) s_wready <= 1'b0;
end

//read signal
always@(posedge aclk)
begin
    if(~aresetn) begin
        s_rdata  <= 'b0;
        s_rvalid <= 1'b0;
        s_rlast  <= 1'b0;
    end
    else if(busy & !write & !r_retire)
    begin
        s_rdata <= rdata_d;
        s_rvalid <= 1'b1;
        s_rlast <= 1'b1; 
    end
    else if(r_retire)
    begin
        s_rvalid <= 1'b0;
    end
end

//bvalid
always@(posedge aclk)
begin
    if(~aresetn) s_bvalid <= 1'b0;
    else if(w_enter) s_bvalid <= 1'b1;
    else if(b_retire) s_bvalid <= 1'b0;
end

assign s_rid   = buf_id;
assign s_bid   = buf_id;
assign s_bresp = 2'b0;
assign s_rresp = 2'b0;

// SM4 reg
reg [31:0]	sm4_enable_in_reg;		//00
reg [31:0]	encdec_enable_in_reg;	//04
reg [31:0]	encdec_sel_in_reg;		//08
reg [31:0]	valid_in_reg;			//0c
reg [31:0]	data_in_reg_3;			//10
reg [31:0]	data_in_reg_2;			//14
reg [31:0]	data_in_reg_1;			//18
reg [31:0]	data_in_reg_0;			//1c
reg [31:0]	enable_key_exp_in_reg;	//20
reg [31:0]	user_key_valid_in_reg;	//24
reg [31:0]	user_key_in_reg_3;		//28
reg [31:0]	user_key_in_reg_2;		//2c
reg [31:0]	user_key_in_reg_1;		//30
reg [31:0]	user_key_in_reg_0;		//34
reg [31:0]	ready_out_reg;			//38
reg [31:0]	key_exp_ready_out_reg;	//3c
reg [31:0]	result_out_reg_0;		//40
reg [31:0]	result_out_reg_1;		//44
reg [31:0]	result_out_reg_2;		//48
reg [31:0]	result_out_reg_3;		//4c
reg [31:0]  sm4_enable_int;			//50

//SM3 reg
reg [31:0]	msg_inpt_d_reg;			//00
reg [31:0]	msg_inpt_vld_byte_reg;	//04
reg [31:0]	msg_inpt_vld_reg;		//08
reg [31:0]	msg_inpt_lst_reg;		//0c
reg [31:0]	msg_inpt_rdy_reg;		//10
reg [31:0]	cmprss_otpt_res_reg_0;	//14
reg [31:0]	cmprss_otpt_res_reg_1;	//18
reg [31:0]	cmprss_otpt_res_reg_2;	//1c
reg [31:0]	cmprss_otpt_res_reg_3;	//20
reg [31:0]	cmprss_otpt_res_reg_4;	//24
reg [31:0]	cmprss_otpt_res_reg_5;	//28
reg [31:0]	cmprss_otpt_res_reg_6;	//2c
reg [31:0]	cmprss_otpt_res_reg_7;	//30
reg [31:0]	cmprss_otpt_vld_reg;	//34
reg [31:0]  sm3_enable_int;			//38

//sm2 reg
reg [31:0] sm2_ecc_start_reg;		//00
reg [31:0] sm2_ecc_done_reg;		//04
reg [31:0] sm2_func_select_reg;		//08
reg [31:0] sm2_curve_select_reg;	//0c
reg [31:0] sm2_private_key_reg_0;	//10
reg [31:0] sm2_private_key_reg_1;	//14
reg [31:0] sm2_private_key_reg_2;	//18
reg [31:0] sm2_private_key_reg_3;	//1c
reg [31:0] sm2_private_key_reg_4;	//20
reg [31:0] sm2_private_key_reg_5;	//24
reg [31:0] sm2_private_key_reg_6;	//28
reg [31:0] sm2_private_key_reg_7;	//2c
reg [31:0] sm2_pubkey_x_reg_0;		//30
reg [31:0] sm2_pubkey_x_reg_1;		//34
reg [31:0] sm2_pubkey_x_reg_2;		//38
reg [31:0] sm2_pubkey_x_reg_3;		//3c
reg [31:0] sm2_pubkey_x_reg_4;		//40
reg [31:0] sm2_pubkey_x_reg_5;		//44
reg [31:0] sm2_pubkey_x_reg_6;		//48
reg [31:0] sm2_pubkey_x_reg_7;		//4c
reg [31:0] sm2_pubkey_y_reg_0;		//50
reg [31:0] sm2_pubkey_y_reg_1;		//54
reg [31:0] sm2_pubkey_y_reg_2;		//58	
reg [31:0] sm2_pubkey_y_reg_3;		//5c
reg [31:0] sm2_pubkey_y_reg_4;		//60
reg [31:0] sm2_pubkey_y_reg_5;		//64
reg [31:0] sm2_pubkey_y_reg_6;		//68
reg [31:0] sm2_pubkey_y_reg_7;		//6c
reg [31:0] sm2_k_random_reg_0;		//70
reg [31:0] sm2_k_random_reg_1;		//74
reg [31:0] sm2_k_random_reg_2;		//78
reg [31:0] sm2_k_random_reg_3;		//7c
reg [31:0] sm2_k_random_reg_4;		//80
reg [31:0] sm2_k_random_reg_5;		//84
reg [31:0] sm2_k_random_reg_6;		//88
reg [31:0] sm2_k_random_reg_7;		//8c
reg [31:0] sm2_signature_s_reg_0;	//90
reg [31:0] sm2_signature_s_reg_1;	//94
reg [31:0] sm2_signature_s_reg_2;	//98
reg [31:0] sm2_signature_s_reg_3;	//9c
reg [31:0] sm2_signature_s_reg_4;	//a0
reg [31:0] sm2_signature_s_reg_5;	//a4
reg [31:0] sm2_signature_s_reg_6;	//a8
reg [31:0] sm2_signature_s_reg_7;	//ac
reg [31:0] sm2_signature_r_reg_0;	//b0
reg [31:0] sm2_signature_r_reg_1;	//b4
reg [31:0] sm2_signature_r_reg_2;	//b8
reg [31:0] sm2_signature_r_reg_3;	//bc
reg [31:0] sm2_signature_r_reg_4;	//c0
reg [31:0] sm2_signature_r_reg_5;	//c4
reg [31:0] sm2_signature_r_reg_6;	//c8
reg [31:0] sm2_signature_r_reg_7;	//cc
reg [31:0] sm2_hash_done_reg;		//d0
reg [31:0] sm2_hash_result_reg_0;	//d4
reg [31:0] sm2_hash_result_reg_1;	//d8
reg [31:0] sm2_hash_result_reg_2;	//dc
reg [31:0] sm2_hash_result_reg_3;	//e0
reg [31:0] sm2_hash_result_reg_4;	//e4
reg [31:0] sm2_hash_result_reg_5;	//e8
reg [31:0] sm2_hash_result_reg_6;	//ec
reg [31:0] sm2_hash_result_reg_7;	//f0
reg [31:0] sm2_verify_ok_reg;		//f4
reg [31:0] sm2_ecc_state_reg;		//f8
reg [31:0] sm2_error_code_reg;		//fc
reg [31:0] sm2_result_s_reg_0;		//100
reg [31:0] sm2_result_s_reg_1;		//104
reg [31:0] sm2_result_s_reg_2;		//108
reg [31:0] sm2_result_s_reg_3;		//10c
reg [31:0] sm2_result_s_reg_4;		//110
reg [31:0] sm2_result_s_reg_5;		//114
reg [31:0] sm2_result_s_reg_6;		//118
reg [31:0] sm2_result_s_reg_7;		//11c
reg [31:0] sm2_result_r_reg_0;		//120
reg [31:0] sm2_result_r_reg_1;		//124
reg [31:0] sm2_result_r_reg_2;		//128
reg [31:0] sm2_result_r_reg_3;		//12c
reg [31:0] sm2_result_r_reg_4;		//130
reg [31:0] sm2_result_r_reg_5;		//134
reg [31:0] sm2_result_r_reg_6;		//138
reg [31:0] sm2_result_r_reg_7;		//13c
reg [31:0] sm2_enable_int;			//140
reg [31:0] sm2_cowork_sm3;			//144

//key reg
reg [31:0] key_type_reg;		//00
reg [31:0] key_index_reg;		//04
reg [31:0] key_pin_reg_0;		//08
reg [31:0] key_pin_reg_1;		//0c
reg [31:0] key_1_in_reg_0;		//10
reg [31:0] key_1_in_reg_1;		//14
reg [31:0] key_1_in_reg_2;		//18
reg [31:0] key_1_in_reg_3;		//1c
reg [31:0] key_1_in_reg_4;		//20
reg [31:0] key_1_in_reg_5;		//24
reg [31:0] key_1_in_reg_6;		//28
reg [31:0] key_1_in_reg_7;		//2c
reg [31:0] key_2_in_reg_0;		//30
reg [31:0] key_2_in_reg_1;		//34
reg [31:0] key_2_in_reg_2;		//38	
reg [31:0] key_2_in_reg_3;		//3c
reg [31:0] key_2_in_reg_4;		//40
reg [31:0] key_2_in_reg_5;		//44
reg [31:0] key_2_in_reg_6;		//48
reg [31:0] key_2_in_reg_7;		//4c
reg [31:0] key_1_out_reg_0;		//50
reg [31:0] key_1_out_reg_1;		//54
reg [31:0] key_1_out_reg_2;		//58
reg [31:0] key_1_out_reg_3;		//5c
reg [31:0] key_1_out_reg_4;		//60
reg [31:0] key_1_out_reg_5;		//64
reg [31:0] key_1_out_reg_6;		//68
reg [31:0] key_1_out_reg_7;		//6c
reg [31:0] key_2_out_reg_0;		//70
reg [31:0] key_2_out_reg_1;		//74
reg [31:0] key_2_out_reg_2;		//78	
reg [31:0] key_2_out_reg_3;		//7c
reg [31:0] key_2_out_reg_4;		//80
reg [31:0] key_2_out_reg_5;		//84
reg [31:0] key_2_out_reg_6;		//88
reg [31:0] key_2_out_reg_7;		//8c
reg [31:0] key_ready_reg;		//90
reg [31:0] key_state_reg;		//94
reg [31:0] key_use_int_key;		//98
reg [31:0] key_mode_reg;			//9c
reg [31:0] key_3_in_reg_0;		//a0
reg [31:0] key_3_in_reg_1;		//a4
reg [31:0] key_3_in_reg_2;		//a8	
reg [31:0] key_3_in_reg_3;		//ac
reg [31:0] key_3_in_reg_4;		//b0
reg [31:0] key_3_in_reg_5;		//b4
reg [31:0] key_3_in_reg_6;		//b8
reg [31:0] key_3_in_reg_7;		//bc
reg [31:0] key_3_out_reg_0;		//c0
reg [31:0] key_3_out_reg_1;		//c4
reg [31:0] key_3_out_reg_2;		//c8	
reg [31:0] key_3_out_reg_3;		//cc
reg [31:0] key_3_out_reg_4;		//d0
reg [31:0] key_3_out_reg_5;		//d4
reg [31:0] key_3_out_reg_6;		//d8
reg [31:0] key_3_out_reg_7;		//dc
reg [31:0] key_in_valid_reg;	//e0


//read DATA						//sm4
assign      rdata_d =   buf_addr[15:0] == (`SM4_BASE_ADDR + 16'h38) ? ready_out_reg :
						buf_addr[15:0] == (`SM4_BASE_ADDR + 16'h3c) ? key_exp_ready_out_reg :
						buf_addr[15:0] == (`SM4_BASE_ADDR + 16'h40) ? result_out_reg_0 :
						buf_addr[15:0] == (`SM4_BASE_ADDR + 16'h44) ? result_out_reg_1 :
						buf_addr[15:0] == (`SM4_BASE_ADDR + 16'h48) ? result_out_reg_2 :
						buf_addr[15:0] == (`SM4_BASE_ADDR + 16'h4c) ? result_out_reg_3 :
						//sm3
						buf_addr[15:0] == (`SM3_BASE_ADDR + 16'h10) ? msg_inpt_rdy_reg :
						buf_addr[15:0] == (`SM3_BASE_ADDR + 16'h14) ? cmprss_otpt_res_reg_0 :
						buf_addr[15:0] == (`SM3_BASE_ADDR + 16'h18) ? cmprss_otpt_res_reg_1 :
						buf_addr[15:0] == (`SM3_BASE_ADDR + 16'h1c) ? cmprss_otpt_res_reg_2 :
						buf_addr[15:0] == (`SM3_BASE_ADDR + 16'h20) ? cmprss_otpt_res_reg_3 :
						buf_addr[15:0] == (`SM3_BASE_ADDR + 16'h24) ? cmprss_otpt_res_reg_4 :
						buf_addr[15:0] == (`SM3_BASE_ADDR + 16'h28) ? cmprss_otpt_res_reg_5 :
						buf_addr[15:0] == (`SM3_BASE_ADDR + 16'h2c) ? cmprss_otpt_res_reg_6 :
						buf_addr[15:0] == (`SM3_BASE_ADDR + 16'h30) ? cmprss_otpt_res_reg_7 :
						buf_addr[15:0] == (`SM3_BASE_ADDR + 16'h34) ? cmprss_otpt_vld_reg :
						//sm2
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h04) ? sm2_ecc_done_reg :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h100) ? sm2_result_s_reg_0 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h104) ? sm2_result_s_reg_1 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h108) ? sm2_result_s_reg_2 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h10c) ? sm2_result_s_reg_3 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h110) ? sm2_result_s_reg_4 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h114) ? sm2_result_s_reg_5 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h118) ? sm2_result_s_reg_6 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h11c) ? sm2_result_s_reg_7 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h120) ? sm2_result_r_reg_0 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h124) ? sm2_result_r_reg_1 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h128) ? sm2_result_r_reg_2 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h12c) ? sm2_result_r_reg_3 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h130) ? sm2_result_r_reg_4 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h134) ? sm2_result_r_reg_5 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h138) ? sm2_result_r_reg_6 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'h13c) ? sm2_result_r_reg_7 :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'hf4) ? sm2_verify_ok_reg :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'hf8) ? sm2_ecc_state_reg :
						buf_addr[15:0] == (`SM2_BASE_ADDR + 16'hfc) ? sm2_error_code_reg :
						//key
						`ifdef ENABLE_SOFTWARE_KEY_OUT
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h50) ? key_1_out_reg_0 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h54) ? key_1_out_reg_1 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h58) ? key_1_out_reg_2 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h5c) ? key_1_out_reg_3 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h60) ? key_1_out_reg_4 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h64) ? key_1_out_reg_5 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h68) ? key_1_out_reg_6 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h6c) ? key_1_out_reg_7 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h70) ? key_2_out_reg_0 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h74) ? key_2_out_reg_1 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h78) ? key_2_out_reg_2 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h7c) ? key_2_out_reg_3 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h80) ? key_2_out_reg_4 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h84) ? key_2_out_reg_5 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h88) ? key_2_out_reg_6 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h8c) ? key_2_out_reg_7 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'hc0) ? key_3_out_reg_0 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'hc4) ? key_3_out_reg_1 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'hc8) ? key_3_out_reg_2 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'hcc) ? key_3_out_reg_3 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'hd0) ? key_3_out_reg_4 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'hd4) ? key_3_out_reg_5 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'hd8) ? key_3_out_reg_6 :
							buf_addr[15:0] == (`KEY_BASE_ADDR + 16'hdc) ? key_3_out_reg_7 :
						`endif
						buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h90) ? key_ready_reg :
						buf_addr[15:0] == (`KEY_BASE_ADDR + 16'h94) ? key_state_reg :
						//sim
						buf_addr[15:0] == `SIMU_FLAG_ADDR ? simu_flag : 32'd0;

	//write data enable
	//sm4
	wire write_sm4_enable_in_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h0);
	wire write_encdec_enable_in_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h4);
	wire write_encdec_sel_in_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h8);
	wire write_valid_in_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'hc);
	wire write_data_in_reg_0_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h10);
	wire write_data_in_reg_1_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h14);
	wire write_data_in_reg_2_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h18);
	wire write_data_in_reg_3_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h1c);
	wire write_enable_key_exp_in_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h20);
	wire write_user_key_valid_in_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h24);
	wire write_user_key_in_reg_0_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h28);
	wire write_user_key_in_reg_1_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h2c);
	wire write_user_key_in_reg_2_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h30);
	wire write_user_key_in_reg_3_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h34);
	wire write_sm4_enable_int_en = w_enter & (buf_addr[15:0] == `SM4_BASE_ADDR + 16'h50);
	//SM3
	wire write_msg_inpt_d_reg_en = w_enter & (buf_addr[15:0] == `SM3_BASE_ADDR + 16'h0);
	wire write_msg_inpt_vld_byte_reg_en = w_enter & (buf_addr[15:0] == `SM3_BASE_ADDR + 16'h4);
	wire write_msg_inpt_vld_reg_en = w_enter & (buf_addr[15:0] == `SM3_BASE_ADDR + 16'h8);
	wire write_msg_inpt_lst_reg_en = w_enter & (buf_addr[15:0] == `SM3_BASE_ADDR + 16'hc);
	wire write_sm3_enable_int_en = w_enter & (buf_addr[15:0] == `SM3_BASE_ADDR + 16'h38);
	//SM2
	wire write_sm2_ecc_start_reg_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h00);
	wire write_sm2_func_select_reg_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h08);
	wire write_sm2_curve_select_reg_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h0c);
	wire write_sm2_private_key_reg_0_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h10);
	wire write_sm2_private_key_reg_1_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h14);
	wire write_sm2_private_key_reg_2_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h18);
	wire write_sm2_private_key_reg_3_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h1c);
	wire write_sm2_private_key_reg_4_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h20);
	wire write_sm2_private_key_reg_5_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h24);
	wire write_sm2_private_key_reg_6_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h28);
	wire write_sm2_private_key_reg_7_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h2c);
	wire write_sm2_pubkey_x_reg_0_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h30);
	wire write_sm2_pubkey_x_reg_1_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h34);
	wire write_sm2_pubkey_x_reg_2_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h38);
	wire write_sm2_pubkey_x_reg_3_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h3c);
	wire write_sm2_pubkey_x_reg_4_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h40);
	wire write_sm2_pubkey_x_reg_5_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h44);
	wire write_sm2_pubkey_x_reg_6_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h48);
	wire write_sm2_pubkey_x_reg_7_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h4c);
	wire write_sm2_pubkey_y_reg_0_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h50);
	wire write_sm2_pubkey_y_reg_1_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h54);
	wire write_sm2_pubkey_y_reg_2_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h58);
	wire write_sm2_pubkey_y_reg_3_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h5c);
	wire write_sm2_pubkey_y_reg_4_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h60);
	wire write_sm2_pubkey_y_reg_5_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h64);
	wire write_sm2_pubkey_y_reg_6_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h68);
	wire write_sm2_pubkey_y_reg_7_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h6c);
	wire write_sm2_k_random_reg_0_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h70);
	wire write_sm2_k_random_reg_1_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h74);
	wire write_sm2_k_random_reg_2_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h78);
	wire write_sm2_k_random_reg_3_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h7c);
	wire write_sm2_k_random_reg_4_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h80);
	wire write_sm2_k_random_reg_5_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h84);
	wire write_sm2_k_random_reg_6_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h88);
	wire write_sm2_k_random_reg_7_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h8c);
	wire write_sm2_signature_s_reg_0_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h90);
	wire write_sm2_signature_s_reg_1_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h94);
	wire write_sm2_signature_s_reg_2_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h98);
	wire write_sm2_signature_s_reg_3_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h9c);
	wire write_sm2_signature_s_reg_4_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'ha0);
	wire write_sm2_signature_s_reg_5_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'ha4);
	wire write_sm2_signature_s_reg_6_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'ha8);
	wire write_sm2_signature_s_reg_7_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hac);
	wire write_sm2_signature_r_reg_0_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hb0);
	wire write_sm2_signature_r_reg_1_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hb4);
	wire write_sm2_signature_r_reg_2_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hb8);
	wire write_sm2_signature_r_reg_3_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hbc);
	wire write_sm2_signature_r_reg_4_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hc0);
	wire write_sm2_signature_r_reg_5_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hc4);
	wire write_sm2_signature_r_reg_6_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hc8);
	wire write_sm2_signature_r_reg_7_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hcc);
	wire write_sm2_hash_done_reg_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hd0);
	wire write_sm2_hash_result_reg_0_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hd4);
	wire write_sm2_hash_result_reg_1_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hd8);
	wire write_sm2_hash_result_reg_2_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hdc);
	wire write_sm2_hash_result_reg_3_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'he0);
	wire write_sm2_hash_result_reg_4_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'he4);
	wire write_sm2_hash_result_reg_5_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'he8);
	wire write_sm2_hash_result_reg_6_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hec);
	wire write_sm2_hash_result_reg_7_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'hf0);
	wire write_sm2_enable_int_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h140);
	wire write_sm2_cowork_sm3_en = w_enter & (buf_addr[15:0] == `SM2_BASE_ADDR + 16'h144);
	//key
	wire write_key_type_reg_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h00);
	wire write_key_index_reg_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h04);
	wire write_key_pin_reg_0_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h08);
	wire write_key_pin_reg_1_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h0c);
	wire write_key_1_in_reg_0_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h10);
	wire write_key_1_in_reg_1_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h14);
	wire write_key_1_in_reg_2_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h18);
	wire write_key_1_in_reg_3_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h1c);
	wire write_key_1_in_reg_4_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h20);
	wire write_key_1_in_reg_5_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h24);
	wire write_key_1_in_reg_6_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h28);
	wire write_key_1_in_reg_7_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h2c);
	wire write_key_2_in_reg_0_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h30);
	wire write_key_2_in_reg_1_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h34);
	wire write_key_2_in_reg_2_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h38);
	wire write_key_2_in_reg_3_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h3c);
	wire write_key_2_in_reg_4_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h40);
	wire write_key_2_in_reg_5_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h44);
	wire write_key_2_in_reg_6_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h48);
	wire write_key_2_in_reg_7_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h4c);
	wire write_key_3_in_reg_0_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'ha0);
	wire write_key_3_in_reg_1_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'ha4);
	wire write_key_3_in_reg_2_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'ha8);
	wire write_key_3_in_reg_3_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'hac);
	wire write_key_3_in_reg_4_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'hb0);
	wire write_key_3_in_reg_5_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'hb4);
	wire write_key_3_in_reg_6_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'hb8);
	wire write_key_3_in_reg_7_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'hbc);
	wire write_key_use_int_key_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h98);
	wire write_key_mode_reg_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'h9c);
	wire write_key_in_valid_reg_en = w_enter & (buf_addr[15:0] == `KEY_BASE_ADDR + 16'he0);

//write data
always @(posedge aclk or negedge aresetn) begin
    if (!aresetn) begin
		//sm4
        sm4_enable_in_reg <= 32'b0;
		encdec_enable_in_reg <= 32'b0;
		encdec_sel_in_reg <= 32'b0;
		valid_in_reg <= 32'b0;
		data_in_reg_0 <= 32'b0;
		data_in_reg_1 <= 32'b0;
		data_in_reg_2 <= 32'b0;
		data_in_reg_3 <= 32'b0;
		enable_key_exp_in_reg <= 32'b0;
		user_key_valid_in_reg <= 32'b0;
		user_key_in_reg_0 <= 32'b0;
		user_key_in_reg_1 <= 32'b0;
		user_key_in_reg_2 <= 32'b0;
		user_key_in_reg_3 <= 32'b0;
		sm4_enable_int <= 32'b0;
		//SM3
		msg_inpt_d_reg <= 32'b0;
		msg_inpt_vld_byte_reg <= 32'b0;
		msg_inpt_vld_reg <= 32'b0;
		msg_inpt_lst_reg <= 32'b0;
		sm3_enable_int <= 32'b0;
		//sm2
		sm2_curve_select_reg <= 32'b0;
		sm2_func_select_reg <= 32'b0;
		sm2_hash_done_reg <= 32'b0;
		sm2_private_key_reg_0 <= 32'b0;
		sm2_private_key_reg_1 <= 32'b0;
		sm2_private_key_reg_2 <= 32'b0;
		sm2_private_key_reg_3 <= 32'b0;
		sm2_private_key_reg_4 <= 32'b0;
		sm2_private_key_reg_5 <= 32'b0;
		sm2_private_key_reg_6 <= 32'b0;
		sm2_private_key_reg_7 <= 32'b0;
		sm2_pubkey_x_reg_0 <= 32'b0;
		sm2_pubkey_x_reg_1 <= 32'b0;
		sm2_pubkey_x_reg_2 <= 32'b0;
		sm2_pubkey_x_reg_3 <= 32'b0;
		sm2_pubkey_x_reg_4 <= 32'b0;
		sm2_pubkey_x_reg_5 <= 32'b0;
		sm2_pubkey_x_reg_6 <= 32'b0;
		sm2_pubkey_x_reg_7 <= 32'b0;
		sm2_pubkey_y_reg_0 <= 32'b0;
		sm2_pubkey_y_reg_1 <= 32'b0;
		sm2_pubkey_y_reg_2 <= 32'b0;
		sm2_pubkey_y_reg_3 <= 32'b0;
		sm2_pubkey_y_reg_4 <= 32'b0;
		sm2_pubkey_y_reg_5 <= 32'b0;
		sm2_pubkey_y_reg_6 <= 32'b0;
		sm2_pubkey_y_reg_7 <= 32'b0;
		sm2_k_random_reg_0 <= 32'b0;
		sm2_k_random_reg_1 <= 32'b0;
		sm2_k_random_reg_2 <= 32'b0;
		sm2_k_random_reg_3 <= 32'b0;
		sm2_k_random_reg_4 <= 32'b0;
		sm2_k_random_reg_5 <= 32'b0;
		sm2_k_random_reg_6 <= 32'b0;
		sm2_k_random_reg_7 <= 32'b0;
		sm2_signature_s_reg_0 <= 32'b0;
		sm2_signature_s_reg_1 <= 32'b0;
		sm2_signature_s_reg_2 <= 32'b0;
		sm2_signature_s_reg_3 <= 32'b0;
		sm2_signature_s_reg_4 <= 32'b0;
		sm2_signature_s_reg_5 <= 32'b0;
		sm2_signature_s_reg_6 <= 32'b0;
		sm2_signature_s_reg_7 <= 32'b0;
		sm2_signature_r_reg_0 <= 32'b0;
		sm2_signature_r_reg_1 <= 32'b0;
		sm2_signature_r_reg_2 <= 32'b0;
		sm2_signature_r_reg_3 <= 32'b0;
		sm2_signature_r_reg_4 <= 32'b0;
		sm2_signature_r_reg_5 <= 32'b0;
		sm2_signature_r_reg_6 <= 32'b0;
		sm2_signature_r_reg_7 <= 32'b0;
		sm2_hash_result_reg_0 <= 32'b0;
		sm2_hash_result_reg_1 <= 32'b0;
		sm2_hash_result_reg_2 <= 32'b0;
		sm2_hash_result_reg_3 <= 32'b0;
		sm2_hash_result_reg_4 <= 32'b0;
		sm2_hash_result_reg_5 <= 32'b0;
		sm2_hash_result_reg_6 <= 32'b0;
		sm2_hash_result_reg_7 <= 32'b0;
		sm2_enable_int <= 32'b0;
		sm2_cowork_sm3 <= 32'b0;
		//key
		key_index_reg <= 32'b0;
		key_type_reg <= 32'b0;
		key_mode_reg <= 32'b0;
		key_pin_reg_0 <= 32'b0;
		key_pin_reg_1 <= 32'b0;
		key_1_in_reg_0 <= 32'b0;
		key_1_in_reg_1 <= 32'b0;
		key_1_in_reg_2 <= 32'b0;
		key_1_in_reg_3 <= 32'b0;
		key_1_in_reg_4 <= 32'b0;
		key_1_in_reg_5 <= 32'b0;
		key_1_in_reg_6 <= 32'b0;
		key_1_in_reg_7 <= 32'b0;
		key_2_in_reg_0 <= 32'b0;
		key_2_in_reg_1 <= 32'b0;
		key_2_in_reg_2 <= 32'b0;
		key_2_in_reg_3 <= 32'b0;
		key_2_in_reg_4 <= 32'b0;
		key_2_in_reg_5 <= 32'b0;
		key_2_in_reg_6 <= 32'b0;
		key_2_in_reg_7 <= 32'b0;
		key_3_in_reg_0 <= 32'b0;
		key_3_in_reg_1 <= 32'b0;
		key_3_in_reg_2 <= 32'b0;
		key_3_in_reg_3 <= 32'b0;
		key_3_in_reg_4 <= 32'b0;
		key_3_in_reg_5 <= 32'b0;
		key_3_in_reg_6 <= 32'b0;
		key_3_in_reg_7 <= 32'b0;
		key_use_int_key <= 32'b0;
		key_in_valid_reg <= 32'b0;
    end
    else begin
		//sm4
        if (write_sm4_enable_in_en) begin
            sm4_enable_in_reg <= s_wdata;
        end
        else if (write_encdec_enable_in_en) begin
            encdec_enable_in_reg <= s_wdata;
        end
        else if (write_encdec_sel_in_en) begin
            encdec_sel_in_reg <= s_wdata;
        end
        else if (write_valid_in_en) begin
            valid_in_reg <= s_wdata;
        end
        else if (write_data_in_reg_0_en) begin
            data_in_reg_0 <= s_wdata;
        end
        else if (write_data_in_reg_1_en) begin
            data_in_reg_1 <= s_wdata;
        end
        else if (write_data_in_reg_2_en) begin
            data_in_reg_2 <= s_wdata;
        end
        else if (write_data_in_reg_3_en) begin
            data_in_reg_3 <= s_wdata;
        end
        else if (write_enable_key_exp_in_en) begin
            enable_key_exp_in_reg <= s_wdata;
        end
        else if (write_user_key_valid_in_en) begin
            user_key_valid_in_reg <= s_wdata;
        end
        else if (write_user_key_in_reg_0_en) begin
            user_key_in_reg_0 <= s_wdata;
        end
        else if (write_user_key_in_reg_1_en) begin
            user_key_in_reg_1 <= s_wdata;
        end
        else if (write_user_key_in_reg_2_en) begin
            user_key_in_reg_2 <= s_wdata;
        end
        else if (write_user_key_in_reg_3_en) begin
            user_key_in_reg_3 <= s_wdata;
        end
        else if (write_sm4_enable_int_en) begin
            sm4_enable_int <= s_wdata;
        end
		//SM3
        else if (write_msg_inpt_d_reg_en) begin
            msg_inpt_d_reg <= s_wdata;
        end
        else if (write_msg_inpt_vld_byte_reg_en) begin
            msg_inpt_vld_byte_reg <= s_wdata;
        end
        else if (write_msg_inpt_vld_reg_en) begin
            msg_inpt_vld_reg <= s_wdata;
        end
        else if (write_msg_inpt_lst_reg_en) begin
            msg_inpt_lst_reg <= s_wdata;
        end
        else if (write_sm3_enable_int_en) begin
            sm3_enable_int <= s_wdata;
        end
		//sm2
        else if (write_sm2_func_select_reg_en) begin
            sm2_func_select_reg <= s_wdata;
        end	
        else if (write_sm2_curve_select_reg_en) begin
            sm2_curve_select_reg <= s_wdata;
        end
        else if (write_sm2_private_key_reg_0_en) begin
            sm2_private_key_reg_0 <= s_wdata;
        end	
        else if (write_sm2_private_key_reg_1_en) begin
            sm2_private_key_reg_1 <= s_wdata;
        end
        else if (write_sm2_private_key_reg_2_en) begin
            sm2_private_key_reg_2 <= s_wdata;
        end	
        else if (write_sm2_private_key_reg_3_en) begin
            sm2_private_key_reg_3 <= s_wdata;
        end	
        else if (write_sm2_private_key_reg_4_en) begin
            sm2_private_key_reg_4 <= s_wdata;
        end	
        else if (write_sm2_private_key_reg_5_en) begin
            sm2_private_key_reg_5 <= s_wdata;
        end	
        else if (write_sm2_private_key_reg_6_en) begin
            sm2_private_key_reg_6 <= s_wdata;
        end	
        else if (write_sm2_private_key_reg_7_en) begin
            sm2_private_key_reg_7 <= s_wdata;
        end
        else if (write_sm2_pubkey_x_reg_0_en) begin
            sm2_pubkey_x_reg_0 <= s_wdata;
        end		
        else if (write_sm2_pubkey_x_reg_1_en) begin
            sm2_pubkey_x_reg_1 <= s_wdata;
        end		
        else if (write_sm2_pubkey_x_reg_2_en) begin
            sm2_pubkey_x_reg_2 <= s_wdata;
        end		
        else if (write_sm2_pubkey_x_reg_3_en) begin
            sm2_pubkey_x_reg_3 <= s_wdata;
        end		
        else if (write_sm2_pubkey_x_reg_4_en) begin
            sm2_pubkey_x_reg_4 <= s_wdata;
        end		
        else if (write_sm2_pubkey_x_reg_5_en) begin
            sm2_pubkey_x_reg_5 <= s_wdata;
        end		
        else if (write_sm2_pubkey_x_reg_6_en) begin
            sm2_pubkey_x_reg_6 <= s_wdata;
        end		
        else if (write_sm2_pubkey_x_reg_7_en) begin
            sm2_pubkey_x_reg_7 <= s_wdata;
        end		
        else if (write_sm2_pubkey_y_reg_0_en) begin
            sm2_pubkey_y_reg_0 <= s_wdata;
        end		
        else if (write_sm2_pubkey_y_reg_1_en) begin
            sm2_pubkey_y_reg_1 <= s_wdata;
        end		
        else if (write_sm2_pubkey_y_reg_2_en) begin
            sm2_pubkey_y_reg_2 <= s_wdata;
        end		
        else if (write_sm2_pubkey_y_reg_3_en) begin
            sm2_pubkey_y_reg_3 <= s_wdata;
        end		
        else if (write_sm2_pubkey_y_reg_4_en) begin
            sm2_pubkey_y_reg_4 <= s_wdata;
        end		
        else if (write_sm2_pubkey_y_reg_5_en) begin
            sm2_pubkey_y_reg_5 <= s_wdata;
        end		
        else if (write_sm2_pubkey_y_reg_6_en) begin
            sm2_pubkey_y_reg_6 <= s_wdata;
        end		
        else if (write_sm2_pubkey_y_reg_7_en) begin
            sm2_pubkey_y_reg_7 <= s_wdata;
        end
        else if (write_sm2_k_random_reg_0_en) begin
            sm2_k_random_reg_0 <= s_wdata;
        end		
        else if (write_sm2_k_random_reg_1_en) begin
            sm2_k_random_reg_1 <= s_wdata;
        end		
        else if (write_sm2_k_random_reg_2_en) begin
            sm2_k_random_reg_2 <= s_wdata;
        end		
        else if (write_sm2_k_random_reg_3_en) begin
            sm2_k_random_reg_3 <= s_wdata;
        end		
        else if (write_sm2_k_random_reg_4_en) begin
            sm2_k_random_reg_4 <= s_wdata;
        end		
        else if (write_sm2_k_random_reg_5_en) begin
            sm2_k_random_reg_5 <= s_wdata;
        end		
        else if (write_sm2_k_random_reg_6_en) begin
            sm2_k_random_reg_6 <= s_wdata;
        end		
        else if (write_sm2_k_random_reg_7_en) begin
            sm2_k_random_reg_7 <= s_wdata;
        end			
        else if (write_sm2_signature_s_reg_0_en) begin
            sm2_signature_s_reg_0 <= s_wdata;
        end		
        else if (write_sm2_signature_s_reg_1_en) begin
            sm2_signature_s_reg_1 <= s_wdata;
        end		
        else if (write_sm2_signature_s_reg_2_en) begin
            sm2_signature_s_reg_2 <= s_wdata;
        end		
        else if (write_sm2_signature_s_reg_3_en) begin
            sm2_signature_s_reg_3 <= s_wdata;
        end		
        else if (write_sm2_signature_s_reg_4_en) begin
            sm2_signature_s_reg_4 <= s_wdata;
        end		
        else if (write_sm2_signature_s_reg_5_en) begin
            sm2_signature_s_reg_5 <= s_wdata;
        end		
        else if (write_sm2_signature_s_reg_6_en) begin
            sm2_signature_s_reg_6 <= s_wdata;
        end		
        else if (write_sm2_signature_s_reg_7_en) begin
            sm2_signature_s_reg_7 <= s_wdata;
        end
		else if (write_sm2_signature_r_reg_0_en) begin
            sm2_signature_r_reg_0 <= s_wdata;
        end		
        else if (write_sm2_signature_r_reg_1_en) begin
            sm2_signature_r_reg_1 <= s_wdata;
        end		
        else if (write_sm2_signature_r_reg_2_en) begin
            sm2_signature_r_reg_2 <= s_wdata;
        end		
        else if (write_sm2_signature_r_reg_3_en) begin
            sm2_signature_r_reg_3 <= s_wdata;
        end		
        else if (write_sm2_signature_r_reg_4_en) begin
            sm2_signature_r_reg_4 <= s_wdata;
        end		
        else if (write_sm2_signature_r_reg_5_en) begin
            sm2_signature_r_reg_5 <= s_wdata;
        end		
        else if (write_sm2_signature_r_reg_6_en) begin
            sm2_signature_r_reg_6 <= s_wdata;
        end		
        else if (write_sm2_signature_r_reg_7_en) begin
            sm2_signature_r_reg_7 <= s_wdata;
        end
        else if (write_sm2_hash_done_reg_en) begin
            sm2_hash_done_reg <= s_wdata;
        end
		else if (write_sm2_hash_result_reg_0_en) begin
            sm2_hash_result_reg_0 <= s_wdata;
        end		
        else if (write_sm2_hash_result_reg_1_en) begin
            sm2_hash_result_reg_1 <= s_wdata;
        end		
        else if (write_sm2_hash_result_reg_2_en) begin
            sm2_hash_result_reg_2 <= s_wdata;
        end		
        else if (write_sm2_hash_result_reg_3_en) begin
            sm2_hash_result_reg_3 <= s_wdata;
        end		
        else if (write_sm2_hash_result_reg_4_en) begin
            sm2_hash_result_reg_4 <= s_wdata;
        end		
        else if (write_sm2_hash_result_reg_5_en) begin
            sm2_hash_result_reg_5 <= s_wdata;
        end		
        else if (write_sm2_hash_result_reg_6_en) begin
            sm2_hash_result_reg_6 <= s_wdata;
        end		
        else if (write_sm2_hash_result_reg_7_en) begin
            sm2_hash_result_reg_7 <= s_wdata;
        end
        else if (write_sm2_enable_int_en) begin
            sm2_enable_int <= s_wdata;
        end
        else if (write_sm2_cowork_sm3_en) begin
            sm2_cowork_sm3 <= s_wdata;
        end
		//key
        else if (write_key_type_reg_en) begin
            key_type_reg <= s_wdata;
        end
        else if (write_key_index_reg_en) begin
            key_index_reg <= s_wdata;
        end
        else if (write_key_pin_reg_1_en) begin
            key_pin_reg_1 <= s_wdata;
        end
        else if (write_key_pin_reg_0_en) begin
            key_pin_reg_0 <= s_wdata;
        end
		else if (write_key_1_in_reg_0_en) begin
			key_1_in_reg_0 <= s_wdata;
        end
		else if (write_key_1_in_reg_1_en) begin
			key_1_in_reg_1 <= s_wdata;
        end
		else if (write_key_1_in_reg_2_en) begin
			key_1_in_reg_2 <= s_wdata;
        end
		else if (write_key_1_in_reg_3_en) begin
			key_1_in_reg_3 <= s_wdata;
        end
		else if (write_key_1_in_reg_4_en) begin
			key_1_in_reg_4 <= s_wdata;
        end
		else if (write_key_1_in_reg_5_en) begin
			key_1_in_reg_5 <= s_wdata;
        end
		else if (write_key_1_in_reg_6_en) begin
			key_1_in_reg_6 <= s_wdata;
        end
		else if (write_key_1_in_reg_7_en) begin
			key_1_in_reg_7 <= s_wdata;
        end
		else if (write_key_2_in_reg_0_en) begin
			key_2_in_reg_0 <= s_wdata;
        end
		else if (write_key_2_in_reg_1_en) begin
			key_2_in_reg_1 <= s_wdata;
        end
		else if (write_key_2_in_reg_2_en) begin
			key_2_in_reg_2 <= s_wdata;
        end
		else if (write_key_2_in_reg_3_en) begin
			key_2_in_reg_3 <= s_wdata;
        end
		else if (write_key_2_in_reg_4_en) begin
			key_2_in_reg_4 <= s_wdata;
        end
		else if (write_key_2_in_reg_5_en) begin
			key_2_in_reg_5 <= s_wdata;
        end
		else if (write_key_2_in_reg_6_en) begin
			key_2_in_reg_6 <= s_wdata;
        end
		else if (write_key_2_in_reg_7_en) begin
			key_2_in_reg_7 <= s_wdata;
        end
		else if (write_key_3_in_reg_0_en) begin
			key_3_in_reg_0 <= s_wdata;
        end
		else if (write_key_3_in_reg_1_en) begin
			key_3_in_reg_1 <= s_wdata;
        end
		else if (write_key_3_in_reg_2_en) begin
			key_3_in_reg_2 <= s_wdata;
        end
		else if (write_key_3_in_reg_3_en) begin
			key_3_in_reg_3 <= s_wdata;
        end
		else if (write_key_3_in_reg_4_en) begin
			key_3_in_reg_4 <= s_wdata;
        end
		else if (write_key_3_in_reg_5_en) begin
			key_3_in_reg_5 <= s_wdata;
        end
		else if (write_key_3_in_reg_6_en) begin
			key_3_in_reg_6 <= s_wdata;
        end
		else if (write_key_3_in_reg_7_en) begin
			key_3_in_reg_7 <= s_wdata;
        end
		else if (write_key_use_int_key_en) begin
			key_use_int_key <= s_wdata;
        end
		else if (write_key_mode_reg_en) begin
			key_mode_reg <= s_wdata;
        end
		else if (write_key_in_valid_reg_en) begin
			key_in_valid_reg <= s_wdata;
        end
		//其他处理
		else
		begin
			//脉冲置0信号
			msg_inpt_vld_reg <= 32'b0;
			user_key_valid_in_reg <= 32'b0;
			valid_in_reg <= 32'b0;
			key_in_valid_reg <= 32'b0;
		end
    end
end
	

	//SM4---------------------------------------------------------------
	//in
	wire sm4_clk;
	wire sm4_resetn;
	assign sm4_clk = aclk;
	assign sm4_resetn = aresetn;
	wire sm4_enable_in;
	wire encdec_enable_in;
	wire encdec_sel_in;
	wire valid_in;
	wire [127: 0] data_in;
	wire enable_key_exp_in;
	wire user_key_valid_in;
	wire [127: 0] user_key_in;
	//out
	wire ready_out;
	wire key_exp_ready_out;
	wire [127: 0] result_out;
	//reg
	//reg user_key_valid_in_d;
	//reg user_key_valid_in_plus;
	//reg valid_in_d;
	//reg valid_in_plus;
	//in
	assign sm4_enable_in = sm4_enable_in_reg[0];
	assign encdec_enable_in = encdec_enable_in_reg[0];
	assign encdec_sel_in = encdec_sel_in_reg[0];
	assign valid_in = valid_in_reg;
	assign enable_key_exp_in = enable_key_exp_in_reg[0];
	assign user_key_valid_in = user_key_valid_in_reg;
	//key
	assign user_key_in[7:0] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_7[31:24] : user_key_in_reg_3[31:24];
	assign user_key_in[15:8] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_7[23:16] : user_key_in_reg_3[23:16];
	assign user_key_in[23:16] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_7[15:8]  : user_key_in_reg_3[15:8];
	assign user_key_in[31:24] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_7[7:0]   : user_key_in_reg_3[7:0];
	assign user_key_in[39:32] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_6[31:24] : user_key_in_reg_2[31:24];
	assign user_key_in[47:40] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_6[23:16] : user_key_in_reg_2[23:16];
	assign user_key_in[55:48] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_6[15:8]  : user_key_in_reg_2[15:8];
	assign user_key_in[63:56] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_6[7:0]   : user_key_in_reg_2[7:0];
	assign user_key_in[71:64] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_5[31:24] : user_key_in_reg_1[31:24];
	assign user_key_in[79:72] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_5[23:16] : user_key_in_reg_1[23:16];
	assign user_key_in[87:80] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_5[15:8]  : user_key_in_reg_1[15:8];
	assign user_key_in[95:88] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_5[7:0]   : user_key_in_reg_1[7:0];
	assign user_key_in[103:96] 	= (key_use_int_key[0] == 1'b1) ? key_1_out_reg_4[31:24] : user_key_in_reg_0[31:24];
	assign user_key_in[111:104] = (key_use_int_key[0] == 1'b1) ? key_1_out_reg_4[23:16] : user_key_in_reg_0[23:16];
	assign user_key_in[119:112] = (key_use_int_key[0] == 1'b1) ? key_1_out_reg_4[15:8]  : user_key_in_reg_0[15:8];
	assign user_key_in[127:120] = (key_use_int_key[0] == 1'b1) ? key_1_out_reg_4[7:0]   : user_key_in_reg_0[7:0];
	//data
	assign data_in[7:0] 	= data_in_reg_3[31:24];
	assign data_in[15:8] 	= data_in_reg_3[23:16];
	assign data_in[23:16] 	= data_in_reg_3[15:8];
	assign data_in[31:24] 	= data_in_reg_3[7:0];
	assign data_in[39:32] 	= data_in_reg_2[31:24];
	assign data_in[47:40] 	= data_in_reg_2[23:16];
	assign data_in[55:48] 	= data_in_reg_2[15:8];
	assign data_in[63:56] 	= data_in_reg_2[7:0];
	assign data_in[71:64] 	= data_in_reg_1[31:24];
	assign data_in[79:72] 	= data_in_reg_1[23:16];
	assign data_in[87:80] 	= data_in_reg_1[15:8];
	assign data_in[95:88] 	= data_in_reg_1[7:0];
	assign data_in[103:96] 	= data_in_reg_0[31:24];
	assign data_in[111:104] = data_in_reg_0[23:16];
	assign data_in[119:112] = data_in_reg_0[15:8];
	assign data_in[127:120] = data_in_reg_0[7:0];
	//int
	assign sm4_done_int = sm4_enable_int[0] ? ready_out : 1'b0;
	
	//key_exp_ready_out
	always @(posedge sm4_clk or negedge aresetn)
	begin
		if(!aresetn)	
		begin
			key_exp_ready_out_reg <= 32'b0;
		end
		else
		begin
			if(valid_in)
			begin
				key_exp_ready_out_reg <= 32'b0;
			end
			else if(key_exp_ready_out)
			begin
				key_exp_ready_out_reg <= {31'b0, key_exp_ready_out};
			end
		end
	end
	
	//ready_out
	always @(posedge sm4_clk or negedge aresetn)
	begin
		if(!aresetn)	
		begin
			ready_out_reg <= 32'b0;
		end
		else 
		begin
			if(valid_in)
			begin
				ready_out_reg <= 32'b0;
			end
			else if(ready_out)
			begin
				ready_out_reg <= 32'b1;
			end
		end
	end
	
	//rseult
	always @(posedge ready_out or negedge aresetn)
	begin
		if(!aresetn)
		begin
			result_out_reg_3[31:24]		<= 32'b0; 
			result_out_reg_3[23:16]		<= 32'b0;   
			result_out_reg_3[15:8]		<= 32'b0; 
			result_out_reg_3[7:0]		<= 32'b0; 
			result_out_reg_2[31:24]		<= 32'b0; 
			result_out_reg_2[23:16]		<= 32'b0; 
			result_out_reg_2[15:8]		<= 32'b0; 
			result_out_reg_2[7:0] 		<= 32'b0; 
			result_out_reg_1[31:24]		<= 32'b0; 
			result_out_reg_1[23:16]		<= 32'b0;   
			result_out_reg_1[15:8]		<= 32'b0;   
			result_out_reg_1[7:0]		<= 32'b0;  
			result_out_reg_0[31:24]		<= 32'b0;   
			result_out_reg_0[23:16]		<= 32'b0;  
			result_out_reg_0[15:8]		<= 32'b0;  
			result_out_reg_0[7:0]		<= 32'b0; 
		end
		else
		begin
			result_out_reg_3[31:24] 		<= result_out[7:0];   
			result_out_reg_3[23:16] 		<= result_out[15:8];   
			result_out_reg_3[15:8] 			<= result_out[23:16];   
			result_out_reg_3[7:0] 			<= result_out[31:24];   
			result_out_reg_2[31:24] 		<= result_out[39:32];   
			result_out_reg_2[23:16] 		<= result_out[47:40];   
			result_out_reg_2[15:8] 			<= result_out[55:48];   
			result_out_reg_2[7:0] 			<= result_out[63:56];   
			result_out_reg_1[31:24] 		<= result_out[71:64];   
			result_out_reg_1[23:16] 		<= result_out[79:72];   
			result_out_reg_1[15:8] 			<= result_out[87:80];   
			result_out_reg_1[7:0] 			<= result_out[95:88];   
			result_out_reg_0[31:24]			<= result_out[103:96];   
			result_out_reg_0[23:16] 		<= result_out[111:104];   
			result_out_reg_0[15:8] 			<= result_out[119:112];   
			result_out_reg_0[7:0] 			<= result_out[127:120];
		end
	end
	
	//SM4 Module-----
    sm4_top u_sm4(
        .clk		         (sm4_clk		    ),	//时钟
        .reset_n	         (sm4_resetn	    ),	//复位
		
        .sm4_enable_in       (sm4_enable_in     ),	//模块开始工作
        .encdec_enable_in    (encdec_enable_in  ),	//开始加解密
        .encdec_sel_in       (encdec_sel_in     ),	//加密（0）、解密（1）模式选择
        .valid_in            (valid_in          ),	//数据有效
        .data_in             (data_in           ),	//数据输入
		
        .enable_key_exp_in   (enable_key_exp_in ),	//开始输入用户密钥
        .user_key_valid_in   (user_key_valid_in ),	//用户密钥有效
        .user_key_in         (user_key_in       ),	//用户密钥输入（128bit）
		
        .ready_out           (ready_out         ),	//结果准备好
        .key_exp_ready_out   (key_exp_ready_out ),	//外部密钥读取完成
        .result_out          (result_out        )	//结果（128bit）
    );
	//SM4^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


	//SM3---------------------------------------------------------------
	//sys
	wire sm3_clk;
	wire sm3_resetn;
	assign sm3_clk = aclk;
	assign sm3_resetn = aresetn;
	//in
	wire [31:0] msg_inpt_d;
	wire [3:0] msg_inpt_vld_byte;
	wire msg_inpt_vld, msg_inpt_lst;
	assign msg_inpt_d = msg_inpt_d_reg;
	assign msg_inpt_vld_byte = msg_inpt_vld_byte_reg[3:0];
	assign msg_inpt_lst = msg_inpt_lst_reg[0] & msg_inpt_vld_reg[0];	//与 msg_inpt_vld_reg[0]同时有效一个周期
	assign msg_inpt_vld = msg_inpt_vld_reg[0];
		
	//out
	wire msg_inpt_rdy;
	wire cmprss_otpt_vld;
	wire [255:0] cmprss_otpt_res;
	
	always @(msg_inpt_rdy)
	begin
		msg_inpt_rdy_reg <= {31'b0, msg_inpt_rdy};
	end
	
	always @(posedge sm3_clk or negedge aresetn)
	begin
		if(!aresetn)
		begin
			cmprss_otpt_vld_reg <= 32'b0;
		end
		else
		begin
			if(msg_inpt_vld_reg) begin
				cmprss_otpt_vld_reg <= 32'b0;
			end else if (cmprss_otpt_vld)begin
				cmprss_otpt_vld_reg <= 32'b1;
			end
		end
	end

	always @(posedge sm3_clk or negedge aresetn)
	begin
		if(!aresetn)
		begin
			cmprss_otpt_res_reg_0 <= 32'b0;
			cmprss_otpt_res_reg_1 <= 32'b0;
			cmprss_otpt_res_reg_2 <= 32'b0;
			cmprss_otpt_res_reg_3 <= 32'b0;
			cmprss_otpt_res_reg_4 <= 32'b0;
			cmprss_otpt_res_reg_5 <= 32'b0;
			cmprss_otpt_res_reg_6 <= 32'b0;
			cmprss_otpt_res_reg_7 <= 32'b0;
		end
		else
		begin
			if(cmprss_otpt_vld)
			begin
				cmprss_otpt_res_reg_0 <= cmprss_otpt_res[31:0];
				cmprss_otpt_res_reg_1 <= cmprss_otpt_res[63:32];
				cmprss_otpt_res_reg_2 <= cmprss_otpt_res[95:64];
				cmprss_otpt_res_reg_3 <= cmprss_otpt_res[127:96];
				cmprss_otpt_res_reg_4 <= cmprss_otpt_res[159:128];
				cmprss_otpt_res_reg_5 <= cmprss_otpt_res[191:160];
				cmprss_otpt_res_reg_6 <= cmprss_otpt_res[223:192];
				cmprss_otpt_res_reg_7 <= cmprss_otpt_res[255:224];
			end
		end
	end

	//int
	assign sm3_done_int = sm3_enable_int[0] ? cmprss_otpt_vld : 1'b0;

	//SM3 Module
    sm3_top u_sm3 (
        .clk                (sm3_clk),
        .rst_n              (sm3_resetn),
		
        .msg_inpt_d         (msg_inpt_d),
        .msg_inpt_vld_byte  (msg_inpt_vld_byte),
        .msg_inpt_vld       (msg_inpt_vld),
        .msg_inpt_lst       (msg_inpt_lst),
        .msg_inpt_rdy       (msg_inpt_rdy),
        .cmprss_otpt_res    (cmprss_otpt_res),
        .cmprss_otpt_vld    (cmprss_otpt_vld)
    );
	//SM3^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


	//SM2--------------------------------------------------------------
	//sys
	//wire sm2_clk;
	//wire sm2_resetn;
	//in
	wire ecc_start; 
	wire [1:0] func_select;
	wire curve_select;
	wire hash_done;
	wire [255:0] private_key, pubkey_x, pubkey_y, k_random, signature_s, signature_r, hash_result; 
	
	assign ecc_start = sm2_ecc_start_reg[0];
	assign func_select = sm2_func_select_reg[1:0];
	assign curve_select = sm2_curve_select_reg[0];
	assign hash_done = sm2_cowork_sm3 ? cmprss_otpt_vld_reg : sm2_hash_done_reg[0];
	assign private_key = (key_use_int_key[0] == 1'b1) ? {
		key_3_out_reg_0, key_3_out_reg_1, key_3_out_reg_2, key_3_out_reg_3,
		key_3_out_reg_4, key_3_out_reg_5, key_3_out_reg_6, key_3_out_reg_7} : {
		sm2_private_key_reg_0, sm2_private_key_reg_1, sm2_private_key_reg_2, sm2_private_key_reg_3, 
		sm2_private_key_reg_4, sm2_private_key_reg_5, sm2_private_key_reg_6, sm2_private_key_reg_7};
	assign pubkey_x = (key_use_int_key[0] == 1'b1) ? {
		key_1_out_reg_0, key_1_out_reg_1, key_1_out_reg_2, key_1_out_reg_3,
		key_1_out_reg_4, key_1_out_reg_5, key_1_out_reg_6, key_1_out_reg_7} : {
		sm2_pubkey_x_reg_0, sm2_pubkey_x_reg_1, sm2_pubkey_x_reg_2, sm2_pubkey_x_reg_3, 
		sm2_pubkey_x_reg_4, sm2_pubkey_x_reg_5, sm2_pubkey_x_reg_6, sm2_pubkey_x_reg_7};
	assign pubkey_y = (key_use_int_key[0] == 1'b1) ? {
		key_2_out_reg_0, key_2_out_reg_1, key_2_out_reg_2, key_2_out_reg_3,
		key_2_out_reg_4, key_2_out_reg_5, key_2_out_reg_6, key_2_out_reg_7} : {
		sm2_pubkey_y_reg_0, sm2_pubkey_y_reg_1, sm2_pubkey_y_reg_2, sm2_pubkey_y_reg_3, 
		sm2_pubkey_y_reg_4, sm2_pubkey_y_reg_5, sm2_pubkey_y_reg_6, sm2_pubkey_y_reg_7};
	assign k_random = {
		sm2_k_random_reg_0, sm2_k_random_reg_1, sm2_k_random_reg_2, sm2_k_random_reg_3, 
		sm2_k_random_reg_4, sm2_k_random_reg_5, sm2_k_random_reg_6, sm2_k_random_reg_7};	
	assign signature_r = {
		sm2_signature_r_reg_0, sm2_signature_r_reg_1, sm2_signature_r_reg_2, sm2_signature_r_reg_3, 
		sm2_signature_r_reg_4, sm2_signature_r_reg_5, sm2_signature_r_reg_6, sm2_signature_r_reg_7};		
	assign signature_s = {
		sm2_signature_s_reg_0, sm2_signature_s_reg_1, sm2_signature_s_reg_2, sm2_signature_s_reg_3, 
		sm2_signature_s_reg_4, sm2_signature_s_reg_5, sm2_signature_s_reg_6, sm2_signature_s_reg_7};
	assign hash_result = sm2_cowork_sm3 ? cmprss_otpt_res : {
		sm2_hash_result_reg_0, sm2_hash_result_reg_1, sm2_hash_result_reg_2, sm2_hash_result_reg_3, 
		sm2_hash_result_reg_4, sm2_hash_result_reg_5, sm2_hash_result_reg_6, sm2_hash_result_reg_7};
	
	//时钟域转化
	reg [2:0] sm2_ecc_start_reg_count;
	always @(posedge aclk or negedge aresetn) begin
		if (!aresetn) begin
			sm2_ecc_start_reg <= 32'b0;
		end
		else begin
			if (write_sm2_ecc_start_reg_en) begin
				sm2_ecc_start_reg <= s_wdata;
			end
			else if(sm2_ecc_start_reg_count == 3'd2) begin
				sm2_ecc_start_reg <= 32'b0;
			end
		end
	end
	always @(posedge sm2_clk or negedge sm2_resetn) begin
		if (!sm2_resetn) begin
			sm2_ecc_start_reg_count <= 3'b0;
		end
		else begin
			if (sm2_ecc_start_reg[0]) begin
				sm2_ecc_start_reg_count <= sm2_ecc_start_reg_count + 3'b1;
			end
			else begin
				sm2_ecc_start_reg_count <= 3'b0;
			end
		end
	end
	
	//out
	wire [255:0] result_s, result_r;
	wire ecc_done;
	wire [7:0] error_code;
	wire [2:0] ecc_state;
	wire verify_ok;
	
	always @(posedge sm2_clk or negedge sm2_resetn)
	begin
		if(!sm2_resetn)
		begin
			sm2_ecc_done_reg <= 32'b0;
		end
		else
		begin
			if (ecc_done) begin
				sm2_ecc_done_reg <= 32'b1;
			end else if (ecc_start) begin
				sm2_ecc_done_reg <= 32'b0;
			end
		end
	end

	always @(posedge sm2_clk or negedge sm2_resetn)
	begin
		if(!sm2_resetn)
		begin
			sm2_verify_ok_reg <= 32'b0;
		end
		else
		begin
			if (verify_ok) begin
				sm2_verify_ok_reg <= 32'b1;
			end else if (ecc_start) begin
				sm2_verify_ok_reg <= 32'b0;
			end
		end
	end

	always @(posedge sm2_clk or negedge sm2_resetn)
	begin
		if(!sm2_resetn)
		begin
			sm2_result_r_reg_0 <= 32'b0;
			sm2_result_r_reg_1 <= 32'b0;
			sm2_result_r_reg_2 <= 32'b0;
			sm2_result_r_reg_3 <= 32'b0;
			sm2_result_r_reg_4 <= 32'b0;
			sm2_result_r_reg_5 <= 32'b0;
			sm2_result_r_reg_6 <= 32'b0;
			sm2_result_r_reg_7 <= 32'b0;
			sm2_result_s_reg_0 <= 32'b0;
			sm2_result_s_reg_1 <= 32'b0;
			sm2_result_s_reg_2 <= 32'b0;
			sm2_result_s_reg_3 <= 32'b0;
			sm2_result_s_reg_4 <= 32'b0;
			sm2_result_s_reg_5 <= 32'b0;
			sm2_result_s_reg_6 <= 32'b0;
			sm2_result_s_reg_7 <= 32'b0;
		end
		else
		begin
			if(ecc_done)
			begin
				sm2_result_r_reg_7 <= result_r[31:0];
				sm2_result_r_reg_6 <= result_r[63:32];
				sm2_result_r_reg_5 <= result_r[95:64];
				sm2_result_r_reg_4 <= result_r[127:96];
				sm2_result_r_reg_3 <= result_r[159:128];
				sm2_result_r_reg_2 <= result_r[191:160];
				sm2_result_r_reg_1 <= result_r[223:192];
				sm2_result_r_reg_0 <= result_r[255:224];
				sm2_result_s_reg_7 <= result_s[31:0];
				sm2_result_s_reg_6 <= result_s[63:32];
				sm2_result_s_reg_5 <= result_s[95:64];
				sm2_result_s_reg_4 <= result_s[127:96];
				sm2_result_s_reg_3 <= result_s[159:128];
				sm2_result_s_reg_2 <= result_s[191:160];
				sm2_result_s_reg_1 <= result_s[223:192];
				sm2_result_s_reg_0 <= result_s[255:224];
			end
		end
	end
	
	always @(*)
	begin
		sm2_error_code_reg <= {24'b0, error_code};
		sm2_ecc_state_reg <= {29'b0, ecc_state};
	end
	
	//int
	assign sm2_done_int = sm2_enable_int[0] ? ecc_done : 1'b0;	

	//SM2 Module
	ecc_core u_sm2 (
		// 时钟和复位
		.clk              (sm2_clk),        // 系统时钟
		.rst_n            (sm2_resetn),      // 低电平有效复位
		// 控制信号
		.Start            (ecc_start),      // 操作启动信号
		.Done             (ecc_done),       // 操作完成标志
		.FunSel           (func_select),    // 功能选择 [1:0]	 00 signature  01 verify  10 keypair	
		.curve_sel        (curve_select),   // 曲线选择 0 256r1    1 sm2
		// 密钥输入
		.dA               (private_key),    // 私钥输入
		.PA_x             (pubkey_x),       // 公钥X坐标
		.PA_y             (pubkey_y),       // 公钥Y坐标
		// 随机数输入（签名用）
		.random_k         (k_random),       // 随机数k
		// 验签输入
		.s_verify         (signature_s),    // 待验证的s值
		.r_verify         (signature_r),    // 待验证的r值
		// 输出结果
		.s                (result_s),       // 签名s/公钥x
		.r                (result_r),       // 签名r/公钥y
		// 哈希接口
		.Hv_done          (hash_done),      // 哈希完成标志 -sm3
		.Hv_r             (hash_result),    // 哈希结果	  -sm3
		// 状态输出
		.bingo            (verify_ok),      // 验签成功标志
		.State            (ecc_state),      // 状态机输出 [2:0]
		.error            (error_code)      // 错误码 [7:0]   
	);

	//SM2^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


	//KEY--------------------------------------------------------------
	wire key_clk;
	wire key_resetn;
	assign key_clk = aclk;
	assign key_resetn = aresetn;
	wire [63:0]	key_pin = {key_pin_reg_0, key_pin_reg_1};
	wire [255:0] key_1_in = {
		key_1_in_reg_0, key_1_in_reg_1, key_1_in_reg_2, key_1_in_reg_3,
		key_1_in_reg_4, key_1_in_reg_5, key_1_in_reg_6, key_1_in_reg_7};
	wire [255:0] key_2_in = {
		key_2_in_reg_0, key_2_in_reg_1, key_2_in_reg_2, key_2_in_reg_3,
		key_2_in_reg_4, key_2_in_reg_5, key_2_in_reg_6, key_2_in_reg_7};
	wire [255:0] key_3_in = {
		key_3_in_reg_0, key_3_in_reg_1, key_3_in_reg_2, key_3_in_reg_3,
		key_3_in_reg_4, key_3_in_reg_5, key_3_in_reg_6, key_3_in_reg_7};
	wire [255:0] key_1_out, key_2_out, key_3_out;
	wire key_ready;
	wire [1:0] key_state;
	
	always @(posedge key_clk or negedge key_resetn)
	begin
		if(!key_resetn) begin
			key_1_out_reg_7 <= 32'b0;
			key_1_out_reg_6 <= 32'b0;
			key_1_out_reg_5 <= 32'b0;
			key_1_out_reg_4 <= 32'b0;
			key_1_out_reg_3 <= 32'b0;
			key_1_out_reg_2 <= 32'b0;
			key_1_out_reg_1 <= 32'b0;
			key_1_out_reg_0 <= 32'b0;
			key_2_out_reg_7 <= 32'b0;
			key_2_out_reg_6 <= 32'b0;
			key_2_out_reg_5 <= 32'b0;
			key_2_out_reg_4 <= 32'b0;
			key_2_out_reg_3 <= 32'b0;
			key_2_out_reg_2 <= 32'b0;
			key_2_out_reg_1 <= 32'b0;
			key_3_out_reg_0 <= 32'b0;
			key_3_out_reg_7 <= 32'b0;
			key_3_out_reg_6 <= 32'b0;
			key_3_out_reg_5 <= 32'b0;
			key_3_out_reg_4 <= 32'b0;
			key_3_out_reg_3 <= 32'b0;
			key_3_out_reg_2 <= 32'b0;
			key_3_out_reg_1 <= 32'b0;
			key_3_out_reg_0 <= 32'b0;
		end else if (key_ready) begin
			key_1_out_reg_7 <= key_1_out[31:0];
			key_1_out_reg_6 <= key_1_out[63:32];
			key_1_out_reg_5 <= key_1_out[95:64];
			key_1_out_reg_4 <= key_1_out[127:96];
			key_1_out_reg_3 <= key_1_out[159:128];
			key_1_out_reg_2 <= key_1_out[191:160];
			key_1_out_reg_1 <= key_1_out[223:192];
			key_1_out_reg_0 <= key_1_out[255:224];
			key_2_out_reg_7 <= key_2_out[31:0];
			key_2_out_reg_6 <= key_2_out[63:32];
			key_2_out_reg_5 <= key_2_out[95:64];
			key_2_out_reg_4 <= key_2_out[127:96];
			key_2_out_reg_3 <= key_2_out[159:128];
			key_2_out_reg_2 <= key_2_out[191:160];
			key_2_out_reg_1 <= key_2_out[223:192];
			key_2_out_reg_0 <= key_2_out[255:224];
			key_3_out_reg_7 <= key_3_out[31:0];
			key_3_out_reg_6 <= key_3_out[63:32];
			key_3_out_reg_5 <= key_3_out[95:64];
			key_3_out_reg_4 <= key_3_out[127:96];
			key_3_out_reg_3 <= key_3_out[159:128];
			key_3_out_reg_2 <= key_3_out[191:160];
			key_3_out_reg_1 <= key_3_out[223:192];
			key_3_out_reg_0 <= key_3_out[255:224];
			key_state_reg <= {30'b0, key_state};
			key_ready_reg <= 32'b1;
		end else if (key_in_valid_reg[0]) begin
			key_ready_reg <= 32'b0;
		end
	end
	
    // 实例化
    key_table #(
        .SM2_KEY_NUM(2),
        .SM4_KEY_NUM(2)
    ) u_key (
        .clk(key_clk),
        .rst_n(key_resetn),
        .mode(key_mode_reg[1:0]),				//in
        .key_type(key_type_reg[1:0]),	//in
        .key_index(key_index_reg),	//in
        .pin(key_pin),				//in
		.in_valid(key_in_valid_reg[0]),
        .key_1_in(key_1_in),		//in
        .key_2_in(key_2_in),		//in
		.key_3_in(key_3_in),		//in
        .key_1(key_1_out),			//out
        .key_2(key_2_out),			//out
		.key_3(key_3_out),			//out
        .key_ready(key_ready),		//out
        .state(key_state)			//out
    );
	
	//KEY^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

	//--------------------------{simulation flag}begin-----------------------//
	always @(posedge aclk)
	begin
		if(!aresetn) begin
			simu_flag <= {32{SIMULATION}};
		end
		else begin
			simu_flag <= {32{SIMULATION}};
		end
	end
	//---------------------------{simulation flag}end------------------------//

endmodule
